//################################################################################
// MIT License
// Copyright (c) 2024 ZhangYihua
//
// Change Logs:
// Date           Author       Notes
// 2020-11-04     ZhangYihua   first version
//
// Description  : 
//################################################################################

module s_gain_nkpo2 #(  // gain by negative k power of 2
parameter           DW                      = 16,   // data width, must DW>K_MIN
parameter           K_MAX                   = 13,   // Maximum of cfg_k, K_MAX>=1
parameter           K_MIN                   =  5,   // Minimum of cfg_k

// the following parameters are calculated automatically
parameter           KW                      = $clog2(K_MAX+1)  // range [K_MIN:K_MAX]
) ( 
input       signed  [DW-1:0]                id,
output      signed  [DW-K_MIN-1:0]          od,

input               [KW-1:0]                cfg_k       // range [K_MIN:K_MAX], gain = 2^(-k)
);

//################################################################################
// define local varialbe and localparam
//################################################################################

//################################################################################
// main
//################################################################################

assign od = (cfg_k>$unsigned(K_MAX)) ? (id>>>K_MAX) :
            (cfg_k<$unsigned(K_MIN)) ? (id>>>K_MIN) :
                                       (id>>>cfg_k);

//################################################################################
// ASSERTION
//################################################################################

`ifdef CBB_ASSERT_ON
// synopsys translate_off

initial begin
    if (K_MAX<K_MIN) begin
        $error("K_MAX is less than K_MIN.");
        $stop;
    end
end

// synopsys translate_on
`endif

endmodule
